home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 September / Macworld (1998-09).dmg / Shareware World / Info / For Developers / MacZoop 1.8.3 / More Classes / Threads / ZThread.h < prev    next >
Text File  |  1996-11-26  |  4KB  |  145 lines

  1. /*************************************************************************************************
  2. *
  3. *
  4. *            ObjectMacZapp        -- a standard Mac OOP application template
  5. *
  6. *
  7. *
  8. *            ZThread.h            -- an object that implements a single thread of execution.
  9. *
  10. *
  11. *
  12. *
  13. *
  14. *            © 1996, Graham Cox
  15. *
  16. *
  17. *
  18. *
  19. *************************************************************************************************/
  20.  
  21.  
  22. #pragma once
  23.  
  24.  
  25. #ifndef __ZTHREAD__
  26. #define __ZTHREAD__
  27.  
  28.  
  29. #pragma options align=native
  30.  
  31. #include     <Threads.h>
  32. #include    "ZErrors.h"
  33.  
  34. class    ZThread
  35. {
  36. protected:
  37.     
  38.     Boolean     fDone;
  39.     ThreadID     itsID;
  40.     Size        itsStack;
  41.     long         itsPeriod;
  42.     
  43. public:
  44.  
  45.     ZThread( long doPeriod = 0, Size stackSize = 0 );        // Constructor
  46.     virtual ~ZThread();                                        // Destructor
  47.     
  48.     // Do() is called by ThreadEntry() every doPeriod ticks.  This is the default 
  49.     // behaviour for a thread.  If you want something more complex, override ThreadEntry()  
  50.     virtual void Do() {};
  51.     
  52.     // ThreadEntry is the general entry point for the thread.  You should only override
  53.     // this if you don't want to use the default behaviour of calling Do() 
  54.     // periodically (e.g. async I/O perhaps).
  55.     //
  56.     // If you do override ThreadEntry() you must call one of the Yield functions
  57.     // every so often to let all the other threads get a look in.
  58.     virtual void ThreadEntry();   
  59.  
  60.     // SwitchingIn is called just before your thread is switched in to allow
  61.     // you to perform additional context setup (e.g. GrafPorts)
  62.     virtual void SwitchingIn() {};                             
  63.  
  64.     // SwitchingOut is called just before your thread is switched out to allow
  65.     // you to save extra context data.
  66.     virtual void SwitchingOut() {};                              
  67.  
  68.     // IsDone decides whether or not you have finished.  By default this
  69.     // returns fDone.
  70.     //
  71.     // This is used to exit the loop that keeps calling Do() - when IsDone returns
  72.     // TRUE, the thread will finish and terminate.
  73.     virtual inline Boolean IsDone();                                
  74.  
  75.     // SetDoPeriod() allows you to adjust the interval that Do() is called at
  76.     void SetDoPeriod( long doPeriod = 0 );
  77.  
  78.     // Start() actually creates the thread and sets it running
  79.     virtual void Start();                                    
  80.     
  81.     // Stop() stops a thread.  It can be restarted with Restart()
  82.     virtual OSErr Stop();    
  83.     
  84.     // Restart() puts a thread into the Ready state, restarting it after a Stop()                                
  85.     virtual OSErr Restart();
  86.     
  87.     // Terminate() kills a thread
  88.     virtual void Terminate( Boolean fReturnToPool = FALSE );
  89.  
  90.     // GetState() returns current thread state in *pState
  91.     // The states are defined in Threads.h but can be a bit confusing.
  92.     //
  93.     // Basically my understanding is:
  94.     //
  95.     // - kReadyThreadState means that the thread is ready to run but is not the current
  96.     //   thread.  Normal running threads will return this if GetState() is called from
  97.     //   another thread.
  98.     //
  99.     // - kStoppedThreadState means that the thread has been stopped by a Stop() instruction.
  100.     //
  101.     // - kRunningThreadState means that the thread is running *and* is the current thread.
  102.     //   GetState() will return this if it's called from within Do() say.
  103.     //
  104.     ThreadState GetState();
  105.  
  106.     // Returns thread ID
  107.     inline ThreadID GetThreadID()                                 
  108.     {
  109.         return itsID;
  110.     }                    
  111.     
  112.     // Returns available stack space in *freeStack
  113.     void GetStackSpace( unsigned long *freeStack )
  114.     {
  115.         FailOSErr( ThreadCurrentStackSpace( itsID, freeStack) );
  116.     }
  117.  
  118.     // Sleep for ticksToSleep ticks
  119.     virtual void SleepTicks( long ticksToSleep );                        
  120. };
  121.  
  122.  
  123. // ThreadEntryGlue is required because you can't pass a pointer to a virtual member
  124. // function to NewThread - calling a member function implicitly passes a pointer to
  125. // the object + a virtual function cannot be declared as pascal.
  126. //
  127. // Instead, NewThread gets a pointer to ThreadEntryGlue and ThreadEntryGlue calls
  128. // ThreadEntry in the object.  This is possible because ThreadEntryGlue gets a pointer
  129. // to the object as its parameter (otherwise it wouldn't know which object to call!
  130. pascal void * ThreadEntryGlue( ZThread* me );   
  131.  
  132. // SwitchingInGlue() and SwitchingOutGlue() are needed for similar reasons to above.
  133. pascal void SwitchingInGlue( ThreadID threadBeingSwitched, ZThread* me );
  134. pascal void SwitchingOutGlue( ThreadID threadBeingSwitched, ZThread* me );
  135.  
  136. // Utility function - yield for lTicks ticks
  137. void YieldTicks( long lTicks );
  138.  
  139. // Utility function - safe yield
  140. void SafeYield();
  141.  
  142. #pragma options align=reset
  143.  
  144.  
  145. #endif